#coding: utf-8

from pymorphy import get_morph
import logging
from consts import *
from collections import namedtuple

TaggedToken = namedtuple('TaggedToken',['base','graminfo'])


class PyMorphyInterface:
    """
        class to get base form of a word and morphological info
        from pymorpy
        also formatting pymorphy output to a special format
    """

    def __init__(self, dictionaries_path=PYMORPHY_DICTIONARIES_PATH):
        self.pymorphy = get_morph(dictionaries_path)

    def tag_token(self, token):
        """

        """
        if is_digit(token):
            return TaggedToken(token, PropertiesContainer(POS_TAGS.NUMBER))

        base = self.pymorphy.normalize(token.upper())
        graminfo = self.pymorphy.get_graminfo(token.upper())

        #prints base and graminfo
        logging.debug("======Prints base and props======")
        logging.debug(list(base)[0])
        for gitem in graminfo:
            logging.debug("-------graminfo----------")
            for k, v in gitem.items():
                if k in ['class', 'info']:
                    logging.debug( k + ":" + unicode(v) )

        #NOTE: only first graminfo is taken
        #converted_graminfo = self._convert_properties(graminfo[0], token)
        #NOTE: only first baseform is taken [base.pop]
        #return TaggedToken( base.pop(), converted_graminfo)
        baseindex = 1
        graminfoindex = 1
        if len(base) > 1:
            baseindex = int(ask_clarification(CLARIFICATION_QUESTIONS.BASEFORM, token, base))
        if len(graminfo) > 1:
            graminfoindex = int(ask_clarification(CLARIFICATION_QUESTIONS.GRAMINFO, token, map(lambda  x: x['class'],graminfo)))

        return TaggedToken(list(base)[baseindex - 1],self._convert_properties(graminfo[graminfoindex - 1], token))

    def _convert_properties(self, pymorphy_graminfo, token):
        """
              Разбивает массив полученных от pymorphy морфологических признаков
              и возвращает словарь с признаками для русскоязычной МБД:
                  pymorphy_graminfo - массив, полученный с помощью Pymorphy
                  token - слово, морфологические признаки которого обрабатываются
          """
        properties = PropertiesContainer()
        cl = pymorphy_graminfo['class']
        info = pymorphy_graminfo['info']
        #print word, cl, info
        #сущ
        if cl == u'С':
            properties.pos = POS_TAGS.NOUN

            if token[0].isupper():
                properties.spart = 2
            else:
                properties.spart = 1

            self._fill_grcase(info, properties.grcase)
            self._fill_number(info, properties.num)
            self._fill_gen(info, properties.gen)


        elif cl == u'Г':
            properties.pos = POS_TAGS.VERB

            if u'пвл' in info:
                properties.spart = 7
            else:
                properties.spart = 6

                self._fill_number(info, properties.num)
                self._fill_gen(info, properties.gen)
                    #лицо
                if u'1л' in info:
                    properties.face = 1
                elif u'2л' in info:
                    properties.face = 2
                elif u'3л' in info:
                    properties.face = 3

                properties.tense = self._get_tense(info)

                if u'св' in info:
                    properties.perf = 2
                elif u'нсв' in info:
                    properties.perf = 1

                properties.vc = self._get_voice(info)

                if u'сь' in token[-2:] or u'ся' in token[-2:]:
                    properties.refl = 1
                else:
                    properties.refl = 2


        elif cl in [u'П', u'КР_ПРИЛ']:
            if token in ADJECTIVES_TO_PREPOSITION:
                properties.pos = POS_TAGS.PREPOSITION
                return properties
            properties.pos = POS_TAGS.ADJECTIVE
            #c.spart = 'something'

            self._fill_grcase(info, properties.grcase)
            self._fill_number(info, properties.num)
            self._fill_gen(info, properties.gen)

        elif cl in [u'МС', u'МС-ПРЕДК', u'МС-П']:
            properties.pos = POS_TAGS.PRONOUN
            for a in self.pymorphy.normalize(token):
                if a.lower() in [u'я', u'ты', u'он', u'она', u'оно', u'мы', u'вы', u'они']:
                    properties.spart = 3
                elif a.lower() in [u'кто', u'что', u'какой', u'который']:
                    properties.spart = 4
                elif a.lower() in [u'там', u'туда', u'оттуда', u'сюда', u'здесь', u'так', u'тогда', u'потому',
                                   u'поэтому', u'затем', u'всегда', u'иногда', u'везде', u'всюду', u'повсюду', u'как',
                                   u'где', u'куда', u'откуда', u'когда', u'почему', u'зачем', u'отчего', u'как-то',
                                   u'как-нибудь', u'кое-как', u'где-то', u'где-либо', u'где-нибудь', u'кое-где',
                                   u'когда-то', u'когда-нибудь', u'когда-либо', u'зачем-то', u'почему-то', u'никак',
                                   u'нигде', u'негде', u'ниоткуда', u'неоткуда', u'никуда', u'некуда', u'никогда',
                                   u'некогда', u'незачем']:
                    properties.spart = 5

            self._fill_grcase(info, properties.grcase)


            self._fill_number(info, properties.num)

            self._fill_gen(info, properties.gen)


        elif cl in [u'ПРИЧАСТИЕ', u'КР_ПРИЧАСТИЕ']:
            properties.pos = POS_TAGS.PRICHASTIE

            self._fill_number(info, properties.num)
            self._fill_gen(info, properties.gen)

            properties.tense = self._get_tense(info)

            properties.vc = self._get_voice(info)
            if properties.vc == VOICE.ACTIVE:
                properties.spart = 9
            else:
                properties.spart = 10

        elif cl == u'ДЕЕПРИЧАСТИЕ':
            properties.pos = POS_TAGS.DEEPRICHASTIE
            properties.tense = self._get_tense(info)
            properties.vc = self._get_voice(info)
            if properties.vc == VOICE.ACTIVE:
                properties.spart = 9
            else:
                properties.spart = 10

        elif cl == u'ИНФИНИТИВ':
            properties.pos = POS_TAGS.VERB
            properties.spart = 8



        elif cl == u'ЧИСЛ':
            if token.lower() == u'сколько':
                properties.pos = POS_TAGS.PRONOUN
                properties.spart = 4
            else:
                properties.pos = POS_TAGS.COUNTABLE_NUMERAL


        elif cl == u'ЧИСЛ-П':
            properties.pos = POS_TAGS.ORDINAL_NUMERAL

        elif cl == u'Н':
            properties.pos = POS_TAGS.ADVERB
            if u'вопр' in info:
                #делаем местоимение из наречия :)
                #c.pos = 5
                properties.spart = 4

        elif cl == u'ПРЕДК':
            pass

        elif cl == u'ПРЕДЛ':
            properties.pos = POS_TAGS.PREPOSITION

        elif cl == u'СОЮЗ':
            properties.pos = POS_TAGS.CONJUNCTION

        elif cl == u'МЕЖД':
            properties.pos = POS_TAGS.INTERJECTION

        elif cl == u'ЧАСТ':
            if token == u'не':
                properties.pos = POS_TAGS.NOT

        elif cl == u'ВВОДН':
            pass

        return properties

    def _fill_grcase(self, info, grcase):
        if u'им' in info:
            grcase.add(GRCASES.IMENITELNYI)
        if u'рд' in info:
            grcase.add(GRCASES.RODITELNYI)
        if u'дт' in info:
            grcase.add(GRCASES.DATELNYI)
        if u'вн' in info:
            grcase.add(GRCASES.VINITELNYI)
        if u'тв' in info:
            grcase.add(GRCASES.TVORITELNY)
        if u'пр' in info:
            grcase.add(GRCASES.PREDLOZHNYI)

    def _fill_gen(self, info, gen):
        if u'мр' in info:
            gen.add(GEN.MALE)
        if u'жр' in info:
            gen.add(GEN.FEMALE)
        if u'ср' in info:
            gen.add(GEN.SREDNIY)

    def _fill_number(self, info, num):
        if u'ед' in info:
            num.add(NUMBER.SINGULAR)
        if u'мн' in info:
            num.add(NUMBER.PLURAL)
    def _get_tense(self, info):
        tense = None
        if u'нст' in info:
            tense = TENSES.PRESENT
        elif u'прш' in info:
            tense = TENSES.PAST
        elif u'буд' in info:
            tense = TENSES.FUTURE

        return tense
    def _get_voice(self, info):
        vc = None
        if u'дст' in info:
            vc = VOICE.ACTIVE
        elif u'стр' in info:
            vc = VOICE.PASSIVE
        return vc




class PropertiesContainer:
    def __init__(self, pos=None, spart=None, grcase=set(), num=set(), gen=set(), face=None, tense=None, perf=None, vc=None, refl=None):
        self.pos=pos
        self.spart=spart
        self.grcase=grcase
        self.num=num
        self.gen=gen
        self.face=face
        self.tense=tense
        self.perf=perf
        self.vc=vc
        self.refl=refl

    def __str__(self):
        return ''




